package com.wolf.util.http;

import com.wolf.util.JsonUtil;
import com.wolf.util.StringUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.http.*;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.AbstractHttpEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.web.multipart.MultipartFile;

import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author sdyang
 * @create 2017-12-19 16:37
 **/
public class HttpClientUtil {

    private static String CHARSET = "UTF-8";

    private static Header jsonHeader = new BasicHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString());

    /**
     * @param url
     * @param json
     * @return
     */
    public static String post(String url, String json) {
        HttpRequestParam param = HttpRequestParam.getInstance();
        param.setUrl(url);
        param.setData(json);
        return post(param);
    }

    /**
     * @param url
     * @param json
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T post(String url, String json, Class<T> clazz) {
        String response = post(url, json);
        if (StringUtils.isEmpty(response)) {
            return null;
        }
        return JsonUtil.parseObject(response, clazz);
    }

    public static <T> T post(String url, Object object, Class<T> clazz) {
        String response = post(url, JsonUtil.toJSONString(object));
        if (StringUtils.isEmpty(response)) {
            return null;
        }
        return JsonUtil.parseObject(response, clazz);
    }

    /**
     * @param url
     * @param paramsMap
     * @return
     */
    public static String post(String url, Map<String, Object> paramsMap) {
        HttpRequestParam param = HttpRequestParam.getInstance();
        param.setUrl(url);
        param.setParamMap(paramsMap);
        return post(param);
    }

    /**
     * @param url
     * @param paramsMap
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T post(String url, Map<String, Object> paramsMap, Class<T> clazz) {
        String response = post(url, paramsMap);
        return JsonUtil.parseObject(response, clazz);
    }

    /**
     * @param cookies
     * @return
     */
    private static CookieStore getCookie(List<BasicClientCookie> cookies) {
        CookieStore cookieStore = new BasicCookieStore();
        for (BasicClientCookie cookie : cookies) {
            cookieStore.addCookie(cookie);
        }
        return cookieStore;
    }

    /**
     * @param param
     * @return
     */
    public static String post(HttpRequestParam param) {
        HttpClient httpClient = LocalHttpClient.httpClient;

        HttpPost httpPost = null;
        String result = null;
        try {
            httpPost = new HttpPost(param.getUrl());

            //添加头部信息
            if (param.getHeadMap() != null) {
                for (Map.Entry<String, String> entry : param.getHeadMap().entrySet()) {
                    httpPost.setHeader(entry.getKey(), entry.getValue());
                }
            }

            // 设置cookie
            HttpClientContext context = null;
            if (CollectionUtils.isNotEmpty(param.getCookies())) {
                context = HttpClientContext.create();
                context.setCookieStore(getCookie(param.getCookies()));
                context.setCredentialsProvider(new BasicCredentialsProvider());
            }

            //设置参数
            AbstractHttpEntity entity = null;

            if (StringUtils.isNotEmpty(param.getData())) {
                entity = new StringEntity(param.getData(), param.getCharset());
                entity.setContentType(param.getContentType().toString());
                entity.setContentEncoding(CHARSET);
            }


            if (param.getParamMap() != null && param.getParamMap().size() > 0) {
                List<NameValuePair> list = new ArrayList<NameValuePair>();

                for (Map.Entry<String, Object> entry : param.getParamMap().entrySet()) {
                    list.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
                }

                if (list.size() > 0) {
                    entity = new UrlEncodedFormEntity(list, param.getCharset());
                }
            }

            httpPost.setEntity(entity);
            HttpResponse response = null;
            if (context == null) {
                response = httpClient.execute(httpPost);
            } else {
                response = httpClient.execute(httpPost, context);
            }
            if (response != null) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, param.getCharset());
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return result;
    }

    /**
     * @param url
     * @param paramsMap
     * @return
     */
    public static String get(String url, Map<String, Object> paramsMap) {
        HttpRequestParam param = HttpRequestParam.getInstance();
        param.setUrl(url);
        param.setParamMap(paramsMap);
        return get(param);
    }

    /**
     * @param url
     * @param paramMap
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T get(String url, Map<String, Object> paramMap, Class<T> clazz) {
        String response = get(url, paramMap);
        if (StringUtils.isEmpty(response)) {
            return null;
        }
        return JsonUtil.parseObject(response, clazz);
    }

    /**
     * @param param
     * @return
     */
    public static String get(HttpRequestParam param) {

        String resultString = "";

        CloseableHttpResponse response = null;
        try {

            URIBuilder builder = new URIBuilder(param.getUrl());
            if (param.getParamMap() != null) {
                for (Map.Entry<String, Object> entry : param.getParamMap().entrySet()) {
                    builder.addParameter(entry.getKey(), entry.getValue().toString());
                }
            }

            URI uri = builder.build();

            HttpGet httpGet = new HttpGet(uri);

            if (param.getHeadMap() != null) {
                for (Map.Entry<String, String> entry : param.getHeadMap().entrySet()) {
                    httpGet.setHeader(entry.getKey(), entry.getValue());
                }
            }

            // 执行请求
            response = LocalHttpClient.httpClient.execute(httpGet);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                resultString = EntityUtils.toString(response.getEntity(), param.getCharset());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultString;
    }

    /**
     * @param url
     * @param paramsMap
     * @param fileMap
     * @return
     * @author sdyang
     * @date 2019-05-07
     */
    public static String post(String url, Map<String, String> paramsMap, Map<String, MultipartFile> fileMap) {
        HttpClient httpClient = LocalHttpClient.httpClient;
        HttpPost httpPost = null;
        String result = null;
        try {
            httpPost = new HttpPost(url);

            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setCharset(java.nio.charset.Charset.forName(CHARSET));
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            String fileName = null;
            for (Map.Entry<String, MultipartFile> entry : fileMap.entrySet()) {
                fileName = entry.getValue().getOriginalFilename();
                builder.addBinaryBody(entry.getKey(), entry.getValue().getInputStream(), ContentType.MULTIPART_FORM_DATA, fileName);// 文件流
            }

            //决中文乱码
            ContentType contentType = ContentType.TEXT_PLAIN.withCharset(CHARSET);
            for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
                if (entry.getValue() == null)
                    continue;
                builder.addTextBody(entry.getKey(), entry.getValue(), contentType);
            }
            HttpEntity entity = builder.build();
            httpPost.setEntity(entity);
            HttpResponse response = httpClient.execute(httpPost);
            if (response != null) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, CHARSET);
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return result;
    }

}
